package com.hzw.net.page

import android.os.Build
import android.os.Bundle
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.viewbinding.ViewBinding
import com.hzw.core.Rom.isVivo
import com.hzw.core.log.logW
import com.hzw.core.toast.toast
import com.hzw.net.delegate.viewBinding
import com.hzw.net.page.layout.AbsTitleLayout
import com.hzw.net.page.status.*
import com.hzw.net.utils.StatusBarUtils
import com.hzw.net.vm.IView

/**
 *
 * @Author:         HuaZhongWei
 * @CreateDate:     2020/11/4 15:44
 *
 * @Description:    所有Activity的基类，包含了界面组成，状态栏的改变
 *
 */
abstract class BaseActivity<VB : ViewBinding> : AppCompatActivity(), IView {

    open val isNeedTranslucentStatus: Boolean = false

    open val isNeedPageStatusManager: Boolean = true

    var statusManager: PageStatusManager? = null

    /**
     * 不能像layoutResId一样，直接abstract或open直接重写属性
     * 因为会子类重复创建4次，并且最后引用不一致，造成内部方法执行无效
     * 具体原因不清楚，可能跟kotlin的多态有关
     * 最后与Java保持一致的多态操作，重写方法，不重写属性
     */
    var rootTitleLayout: AbsTitleLayout? = null

    /**
     * 状态栏颜色，但是这里不包括Android 5.0的版本
     */
    open val statusBarColor: Int = android.graphics.Color.WHITE

    /**
     * 状态栏颜色，只针对Android 5.0的版本
     * 如vivo 5.0的系统状态栏字体颜色只能是白色，所以状态栏不能为白色，否则看不见
     */
    open val statusBarColorForLollipop: Int = android.graphics.Color.parseColor("#33000000")

    private var _binding: VB? = null

    protected val binding: VB
        get() = _binding!!

    abstract fun getViewBinding(): VB

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        _binding = getViewBinding()
        initSpecialParams()
        initPage()
        initStatusBar()
        initSpecialEvent()
        init(savedInstanceState)
    }

    /**
     * 用于设置一些特殊参数，需要在setContent之前的
     */
    open fun initSpecialParams() {

    }

    /**
     * 初始化一些特殊的事件，放在最底层初始化界面之前
     */
    open fun initSpecialEvent() {

    }

    /**
     * 仅初始化一些与界面相关的操作
     */
    abstract fun init(savedInstanceState: Bundle?)

    private fun initPage() {
        rootTitleLayout = initTitleLayout()
        if (rootTitleLayout != null) { //有标题，那么这里必须套一层，这样保证
            if (isNeedPageStatusManager) { // 需要 loading、空、错误等界面
                createPageStateManager()
                setContentView(statusManager?.rootLayout)
            } else {  //不需要PageStateManager, 没有loading, 空，错误等界面
                createContentLayout()
            }
            rootTitleLayout!!.initUI()
        } else { //没有标题，那么直接使用，这样可以相比之前减少一层布局，提高性能
            if (isNeedPageStatusManager) { // 需要 loading、空、错误等界面
                createPageStateManager()
                setContentView(statusManager?.rootLayout)
            } else { //不需要PageStateManager, 没有loading, 空，错误等界面
                setContentView(binding.root)
            }
        }
    }

    private fun createContentLayout() {
        //第一步：创建容器跟布局
        val rootParams = ViewGroup.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )
        val rootLayout = LinearLayout(this).apply {
            orientation = LinearLayout.VERTICAL
        }

        // 第二步：加入标题
        val titleParams = LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT
        )
        rootLayout.addView(rootTitleLayout!!.rootView, titleParams)

        // 第三步：加入内容
        val contentParams = LinearLayout.LayoutParams(
            ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.MATCH_PARENT
        )

        rootLayout.addView(binding.root, contentParams)

        setContentView(rootLayout, rootParams)
    }

    private fun createPageStateManager() {
        statusManager = initStateManager() ?: PageStatusManager.Builder(this)
            .title(rootTitleLayout?.rootView)
            .content(binding.root)
            .loading(onCreateLoading())
            .empty(onCreateEmpty())
            .error(onCreateError())
            .build()
    }


    open fun initTitleLayout(): AbsTitleLayout? {
        return null
    }

    open fun initStateManager(): PageStatusManager? {
        return null
    }

    override fun onCreateLoading(): ILoadingStatus {
        return LoadingPageStatus(this)
    }

    override fun onCreateEmpty(): IAbnormalStatus {
        return AbnormalPageStatus(this, text = "空", refresh = {
            onRefreshForEmpty(it)
        }, retry = {
            onRetryForEmpty()
        })
    }

    override fun onCreateError(): IAbnormalStatus {
        return AbnormalPageStatus(this, text = "错", refresh = {
            onRefreshForEmpty(it)
        }, retry = {
            onRetryForEmpty()
        })
    }

    /**
     * 改变状态栏颜色
     */
    private fun initStatusBar() {
        if (isNeedTranslucentStatus) {
            StatusBarUtils.setStatusBarTranslucent(this)
        } else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && Build.VERSION.SDK_INT < Build.VERSION_CODES.M && isVivo()) { //5.0及以上
                StatusBarUtils.setStatusBarColor(this, statusBarColorForLollipop)
            } else {
                StatusBarUtils.setStatusBarColor(this, statusBarColor)
            }
            StatusBarUtils.setStatusBarFontAndIconColor(this, true)
        }
    }

    override fun showToast(msg: String?) {
        if (!msg.isNullOrBlank()) {
            toast(msg)
        }
    }

    override fun showLoading(isHideOther: Boolean) {
        statusManager?.showLoading(isHideOther)
    }

    override fun hideLoading() {
        statusManager?.hideLoading()
    }

    override fun showContent() {
        statusManager?.showContent()
    }

    override fun showEmpty() {
        statusManager?.showEmpty(0, "", null)
    }

    override fun showEmpty(imageResId: Int, tipText: String?, retryText: String?) {
        statusManager?.showEmpty(imageResId, tipText ?: "", retryText)
    }

    override fun showError() {
        statusManager?.showError(0, "", null)
    }

    override fun showError(imageResId: Int, tipText: String?, retryText: String?) {
        statusManager?.showError(imageResId, tipText ?: "", retryText)
    }

    override fun handleSpecialEvent(code: Int) {

    }

    override fun onDestroy() {
        super.onDestroy()
        _binding = null
    }
}